package com.brush.brushcommon.aspect;


import com.brush.brushcommon.annotation.NoReSubmit;
import com.brush.brushcommon.dto.Result;
import com.brush.brushcommon.utils.JwtHelper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import java.util.concurrent.TimeUnit;

/**
 * 禁止重复提交 用户处理一些同步处理比较久的api
 */
@Order(-1)
@Component
@Aspect
@Log4j2
public class NoReSubmitAop {

    @Resource
    private RedissonClient redissonClient;

    @Around("@annotation(noReSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, NoReSubmit noReSubmit) throws Throwable {
        RLock lock = null;
        try {
            if (noReSubmit != null) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String uri = request.getRequestURI();
                String key = noReSubmit.keyPrefix() + "_" + JwtHelper.getUserId(request.getHeader("Authorization")) + "_" + uri;
                lock = redissonClient.getLock(key);
                if (!lock.tryLock(0,60,TimeUnit.SECONDS)) {
                    lock = null;
                    throw new RuntimeException(noReSubmit.msg());
                }
            }
            return joinPoint.proceed();
//        }catch (ReLoginTokenException reLoginTokenException){
//            // 这里抛出reLoginTokenException异常，提示前端需要自动重新登陆
//            throw reLoginTokenException;
        }
        catch (Exception e) {
            log.error("禁止重复提交异常：", e);
            return Result.fail(501, e.getMessage());
        } finally {
            if (null != lock) {
                lock.unlock();
            }
        }
    }

}
